<?php
  
  class ActiveRecordCollection extends ActiveCollection {
    
    private $_children_class;
    private $_primary_key;
    private $_whole_structure = array();
    private $_predefined;
    public $class_name;        private $_attributes = array();
    
    private $_array = array();
    private $_first;
    private $_last;
    
    
    
    
    
    
    public function to_array() {
      return $this->_array;
    }
    
    
    public function first() {            $arr = array_values($this->_array);      return $arr[0];
    }        public function last() {      $arr = array_values($this->_array);      return $arr[count($arr) - 1];
    }        public function random () {      $arr = array_values($this->_array);      return $arr[rand (0, count($arr)-1)];          }
    
    
    # Setters
    
    function set_predefined($predefined) {
      $this->_predefined = $predefined;
    }
    
    function set_primary_key($primary_key) {
      $this->_primary_key = $primary_key;
    }
    
    function set_new_element_array($array) {
      $this->_new_element_array = $array;
    }
    
    function set_children_class($children_class) {
      $this->_children_class = $children_class;
    }
    
    
    
    # Getters
    
    function structure() {
      return ActiveRecord::load_class_structure($this->class_name);
    }
    
    function primary_key_name() {
      return $this->_primary_key;
    }
    
    
    
    
    function create($params = array()) {
      $obj = $this->generate($params);
      return $obj->Save();
    }
    
    function generate($params = array()) {
      $children_class = $this->_children_class;
      $predefined = $this->_predefined;
      $params = array_merge($params, $predefined);
      $obj = ActiveRecord::ar_generate($children_class, array($params));
      $this->push($obj);
      return $obj;
    }
    
    function reload_collection_types () {
      /*
      foreach ($this->_array as $key => $record) {
        foreach ($record->structure() as $col) {
          if (!is_a($this->_array[$key]->{$col->field}, 'Date')) {
            switch ($col->type) {
              case 'datetime':
              case 'date':
              case 'time':
              case 'timestamp':
                $this->_array[$key]->{$col->field} = new Date($this->_array[$key]->{$col->field});
                break;
            }
          }
        }
      }
      */
    }
    
    
    
    
    
    
    
    
    
    
    
    public function key_exists($offset) {        return array_key_exists($offset, $this->_array);
    }    
    
    public function offsetExists($offset) {
        return array_key_exists($offset, $this->_array);
    }

    public function offsetGet($offset) {
        return $this->_array[$offset];
    }

    public function offsetSet($offset, $value) {
        $this->_array[$offset] = $value;
    }

    public function offsetUnset($offset) {
        unset($this->_array[$offset]);
    }
    
    public function count() {
      return count($this->_array);
    }
    
    public function current() {
      return current($this->_array);
    }
    
    public function key() {
      return key($this->_array);
    }
    
    public function next() {
      return next($this->_array);
    }
    
    public function rewind() {
      return reset($this->_array);
    }
    
    public function valid() {
      return current($this->_array);
    }
    
    public function __toString() {
      return strval($this->_array);
    }
    
    public function __construct($array = null, $class_name) {
      $this->class_name = $class_name;
      if ($array == null) {
        $this->_array = array();
      } else {
        $this->_array = $array;
      }
      return $this;
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    public function reverse($preserve_keys = false) {
      $obj = clone $this;
      $obj->_array = array_reverse($obj->_array, $preserve_keys);
      return $obj;
    }
    
    public function push() {
      $args = func_get_args();
      $args = str_replace('\'', '\\\'', $args);
      eval ('array_push($this->_array, \'' . join ('\', \'', $args) . '\');');
      return $this;
    }
    
    public function unshift() {
      $args = func_get_args();
      $args = str_replace('\'', '\\\'', $args);
      eval ('array_unshift($this->_array, \'' . join ('\', \'', $args) . '\');');
      return $this;
    }
    
    public function pop($elements = 1) {
      for ($i = 1; $i <= $elements; $i++) {
        array_pop($this->_array);
      }
      if ($elements == 0) {
        $this->_array = array();
      }
      return $this;
    }
    
    public function shift($elements = 1) {
      for ($i = 1; $i <= $elements; $i++) {
        array_shift($this->_array);
      }
      if ($elements == 0) {
        $this->_array = array();
      }
      return $this;
    }
    
    public function join($separator) {
      return join($separator, $this->_array);
    }
    
    public function get_field_table($field_name) {
      $arr = array();
      foreach ($this->_array as $key => $element) {
        $arr[$key] = $element->$field_name;
      }
      return new ActiveCollection($arr);
    }
    
    public function unique() {
      $obj = clone $this;
      $obj->_array = array_unique($obj->_array);
      return $obj;
    }
    
    public function sort() {
      $obj = clone $this;
      sort($obj->_array);
      $obj->_set_first(0);
      $obj->_set_last(count($obj->_array) - 1);
      return $obj;
    }
    
    public function includes($element) {      if (in_array($element->id, $this->get_field_table('id')->to_array())) {
        return true;
      } else {
        return false;
      }
    }
    
    public function map ($function) {
      $obj = clone $this;
      $obj->_array = array_map($function, $obj->_array);
      return $obj;
    }
    
    public function add_keys ($keys_array) {
      if (is_a($keys_array, 'ActiveRecordCollection') || is_a($keys_array, 'ActiveCollection')) {
        $keys_array = $keys_array->to_array();
      }
      $obj = clone $this;
      $obj->_array = array_combine($keys_array, $obj->_array);
      return $obj;
    }
    
    public function transform_to_array($keys_field_name, $values_field_name) {
      $values = $this->get_field_table($values_field_name);
      $keys = $this->get_field_table($keys_field_name);
      return $values->add_keys($keys);
    }            public function set_attributes($atts) {      foreach ($this->_array as $key => $ele) {        $ele->set_attributes($atts);      }    }        public function update_all() {      foreach ($this->_array as $ele) {        $ele->save();      }          }        public function destroy_all() {      foreach ($this->_array as $ele) {        $ele->destroy();      }          }        public function implode ($separator, $prefix = '') {      $str = implode ($separator . $prefix, $this->_array);      if ($str == '') {        return $str;      } else {        return $prefix . $str;      }    }
    
    
    public function keys() {
      $obj = clone $this;
      $obj->_array = array_keys($obj->_array);
      return $obj;
    }  
  }
  
?>